package com.yin.waimai.controller;

import com.yin.waimai.annotation.SensitiveOperation; // 添加导入语句
import com.yin.waimai.dto.AddressDTO;
import com.yin.waimai.dto.CreateOrderRequestDTO;
import com.yin.waimai.dto.OrderDTO;
import com.yin.waimai.enums.OrderStatus;
import com.yin.waimai.model.Address;
import com.yin.waimai.model.LogisticsTrace;
import com.yin.waimai.model.Order;
import com.yin.waimai.service.OrderService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; // <--- Spring Security 导入
import org.springframework.web.bind.annotation.*;

import java.security.Principal; // <--- 用于获取当前用户信息
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {

    private static final Logger log = LoggerFactory.getLogger(OrderController.class);

    private final OrderService orderService;

    @Autowired
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    // 创建订单
    // 假设普通登录用户可以创建订单
    @PostMapping
    @PreAuthorize("isAuthenticated()") // 或者 @PreAuthorize("hasRole('USER')")
    public ResponseEntity<?> createOrder(@Valid @RequestBody CreateOrderRequestDTO requestDTO, Principal principal) {
        log.info("User '{}' received request to create order: {}", principal != null ? principal.getName() : "anonymous", requestDTO);
        try {
            // 将当前登录用户名传递给 OrderService
            String username = principal != null ? principal.getName() : null;
            OrderDTO createdOrder = orderService.createOrder(requestDTO, username); // 修改方法签名，传入用户名
            return ResponseEntity.status(HttpStatus.CREATED).body(createdOrder);
        } catch (Exception e) {
            log.error("Error creating order for user {}: {}", principal != null ? principal.getName() : "anonymous", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("创建订单失败: " + e.getMessage());
        }
    }

    // 查询订单详情 - 假设已登录用户可以查询自己的订单，管理员可以查询任何订单
    // 更复杂的逻辑（如用户只能查询自己的订单）需要在Service层实现
    @GetMapping("/{orderNumber}")
    @PreAuthorize("isAuthenticated()")
    public ResponseEntity<?> getOrderByNumber(@PathVariable String orderNumber, Principal principal) {
        log.info("User '{}' received request to get order by number: {}", principal.getName(), orderNumber);
        // 注意：这里只是简单地允许已认证用户查询。
        // 如果需要实现“用户只能查询自己的订单”的逻辑，你需要在 OrderService 中加入对 principal.getName() 的校验。
        OrderDTO orderDTO = orderService.getOrderByOrderNumber(orderNumber); // 假设 getOrderByOrderNumber 内部处理了找不到的情况或返回 DTO
        if (orderDTO != null) {
            return ResponseEntity.ok(orderDTO);
        } else {
            log.warn("Order not found with number: {} for user {}", orderNumber, principal.getName());
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("订单未找到: " + orderNumber);
        }
    }

    // 查询物流轨迹 - 权限同上 getOrderByNumber
    @GetMapping("/{orderNumber}/traces")
    @PreAuthorize("isAuthenticated()")
    public ResponseEntity<List<LogisticsTrace>> getOrderTraces(@PathVariable String orderNumber, Principal principal) {
        log.info("User '{}' received request to get traces for order number: {}", principal.getName(), orderNumber);
        // 同样，如果需要用户只能查询自己订单的轨迹，Service层需要处理
        OrderDTO order = orderService.getOrderByOrderNumber(orderNumber);
        if (order == null) {
            log.warn("Order not found when trying to get traces for number: {} (User: {})", orderNumber, principal.getName());
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ArrayList<>());
        }
        List<LogisticsTrace> traces = orderService.getLogisticsTracesByOrderNumber(orderNumber);
        return ResponseEntity.ok(traces);
    }

    // 更新订单状态 - 仅允许 ADMIN 或 OPERATOR 角色
    @PutMapping("/{orderNumber}/status")
    @PreAuthorize("hasAnyRole('ADMIN', 'OPERATOR')")
    public ResponseEntity<?> updateOrderStatus(
            @PathVariable String orderNumber,
            @Valid @RequestBody UpdateOrderStatusRequestDTO statusUpdateDTO, Principal principal) {

        log.info("User '{}' (Roles: {}) received request to update status for order {}: {}",
                principal.getName(),
                principal instanceof org.springframework.security.core.Authentication ? ((org.springframework.security.core.Authentication) principal).getAuthorities() : "N/A",
                orderNumber, statusUpdateDTO);
        try {
            // OrderService 的 updateOrderStatusAndAddTrace 方法现在接收的是 OrderStatus 枚举
            OrderDTO updatedOrder = orderService.updateOrderStatusAndAddTrace(
                    orderNumber,
                    statusUpdateDTO.getNewStatus(), // 传递枚举的字符串名称
                    statusUpdateDTO.getOperator(), // 或者直接使用 principal.getName() 作为操作员
                    statusUpdateDTO.getLocation(),
                    statusUpdateDTO.getDescription()
            );
            return ResponseEntity.ok(updatedOrder);
        } catch (IllegalArgumentException e) {
            log.warn("Failed to update order status for {} by user {}: {}", orderNumber, principal.getName(), e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        } catch (RuntimeException e) {
            log.error("Error updating order status for {} by user {}: {}", orderNumber, principal.getName(), e.getMessage(), e);
            if (e.getMessage() != null && e.getMessage().toLowerCase().contains("not found")) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
            }
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("更新订单状态失败: " + e.getMessage());
        }
    }

    // 获取路径规划 - 权限同 getOrderByNumber
    @GetMapping("/{orderNumber}/path")
    @PreAuthorize("isAuthenticated()")
    public ResponseEntity<?> getOrderPath(@PathVariable String orderNumber, Principal principal) {
        log.info("User '{}' received request for path of order {}", principal.getName(), orderNumber);
        // 同样，如果需要用户只能查询自己订单的路径，Service层需要处理
        OrderDTO order = orderService.getOrderByOrderNumber(orderNumber);
        if (order == null) {
            log.warn("Order not found when trying to get path for number: {} (User: {})", orderNumber, principal.getName());
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("订单未找到，无法获取路径");
        }
        List<List<Double>> pathCoordinates = orderService.getOrderRouteCoordinates(orderNumber); // 假设你的OrderService有这个方法
        return ResponseEntity.ok(pathCoordinates != null ? pathCoordinates : new ArrayList<>());
    }

    // 获取当前登录用户信息的API
    @GetMapping("/me")
    @PreAuthorize("isAuthenticated()") // 确保用户已登录
    public ResponseEntity<Object> getCurrentUser(Principal principal) {
        if (principal != null) {
            // 你可以从 principal.getName() 获取用户名，然后从 UserRepository 查询更详细的用户信息
            // 或者直接返回用户名和角色信息
            Object authorities = principal instanceof org.springframework.security.core.Authentication ?
                    ((org.springframework.security.core.Authentication) principal).getAuthorities() : null;
            return ResponseEntity.ok(Map.of(
                    "username", principal.getName(),
                    "roles", authorities
            ));
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); //理论上 @PreAuthorize 会先处理
    }


    // --- DTO 与 Model 转换方法 (你的代码中已经有，这里为了完整性保留注释) ---
    // private Order convertDtoToOrder(CreateOrderRequestDTO dto) { ... }
    // private OrderDTO convertOrderToDto(Order order) { ... }
    // private Address convertAddressDtoToAddress(AddressDTO dto) { ... }
    // private AddressDTO convertAddressToAddressDto(Address address) { ... }

    @Data
    private static class UpdateOrderStatusRequestDTO {
        @NotNull(message = "新状态不能为空")
        private OrderStatus newStatus; // 使用 OrderStatus 枚举
        @NotBlank(message = "操作员不能为空")
        private String operator;
        @NotBlank(message = "地点不能为空")
        private String location;
        @NotBlank(message = "描述不能为空")
        private String description;
    }
    
    // 手动分配配送员
    @PutMapping("/{orderNumber}/assign-delivery-person/{deliveryPersonId}")
    @PreAuthorize("hasAnyRole('ADMIN', 'OPERATOR')")
    public ResponseEntity<?> assignDeliveryPerson(
            @PathVariable String orderNumber,
            @PathVariable String deliveryPersonId,
            Principal principal) {
        
        log.info("User '{}' received request to assign delivery person {} to order {}", 
                principal.getName(), deliveryPersonId, orderNumber);
        
        try {
            OrderDTO updatedOrder = orderService.assignDeliveryPerson(
                    orderNumber,
                    deliveryPersonId,
                    principal.getName()
            );
            return ResponseEntity.ok(updatedOrder);
        } catch (IllegalArgumentException e) {
            log.warn("Failed to assign delivery person for order {} by user {}: {}", 
                    orderNumber, principal.getName(), e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        } catch (RuntimeException e) {
            log.error("Error assigning delivery person for order {} by user {}: {}", 
                    orderNumber, principal.getName(), e.getMessage(), e);
            if (e.getMessage() != null && e.getMessage().toLowerCase().contains("not found")) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
            }
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("分配配送员失败: " + e.getMessage());
        }
    }

    // 自动分配最近的空闲配送员
    // 可以保留手动分配接口，但不再需要自动分配接口
    // 或者将自动分配接口标记为过时
    @Deprecated
    @PutMapping("/{orderNumber}/auto-assign-delivery-person")
    @PreAuthorize("hasAnyRole('ADMIN', 'OPERATOR')")
    public ResponseEntity<?> autoAssignDeliveryPerson(
            @PathVariable String orderNumber,
            Principal principal) {
        
        return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED)
                .body("此功能已被配送员主动接单功能替代");
    }
    
    // 删除订单的方法移到类内部
    @DeleteMapping("/{orderNumber}")
    @PreAuthorize("hasRole('ADMIN')")
    @SensitiveOperation(value = "删除订单", operationType = "DELETE")
    public ResponseEntity<Void> deleteOrder(@PathVariable String orderNumber) {
        orderService.deleteByOrderNumber(orderNumber);
        return ResponseEntity.noContent().build();
    }
}